import java.io.*;
import java.util.Vector;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.awt.*;
import java.awt.Graphics2D;

public class CircuitDraw extends Frame {

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;

	final private int xWinSize = 800;	

	final private int yWinSize = 800;

	private int scale = 3;

  	private int xSize = 1;

	private int ySize = 1;

	private int originX = 200;

	private int originY = 200;

	private int waitTime = 300;	//Alters the speed of the animating.

	private int[][] terrain;

	private int[][] checkpoints;

	private boolean done = false;
	private BufferedImage image;

  	private Vector<Car> cars;

  	private Color[] CarColors = {Color.red, Color.blue, Color.green, Color.magenta};


	public CircuitDraw (Track track) throws IOException {

		terrain=track.getIntTrack();
		checkpoints = track.getCheckpoints();

		this.ySize=terrain.length;
		this.xSize=terrain[0].length;

		this.scale=(int)Math.floor(Math.min(xWinSize/xSize, yWinSize/ySize));

		originX = 100;
		originY = 100;

      init();

   }


   private void init() {

		addWindowListener(new WindowAdapter() { public void

		windowClosing(WindowEvent e) { System.exit(0); } } );

      setSize(xWinSize, yWinSize);

      setTitle("GridRacer: a reinforcement learning cruise control");
   }

	public void update(Vector<Car> newCars) {

		setTitle("Gridracer ");
		cars = newCars;


		repaint();
		try
		{
		Thread.sleep(waitTime);
		}
		catch(InterruptedException ex)
		{
			System.err.println(ex.getMessage());
		}
		}

	public void update(Graphics g) {
		paint(g);
	}


	//convert int to color
	private Graphics2D getColor(int value, Graphics2D g)
	{
		switch (value) {

		// wall
		case 0: {g.setColor(Color.gray);break;}
		// road
		case 1: {g.setColor(Color.black);break;}
		// mud
		case 2: {g.setColor(Color.orange);break;}
		// sand
		case 3: {g.setColor(Color.yellow);break;}

		default:{g.setColor(Color.pink);}
	}
		return g;
	}

	public void paint(Graphics g) {


		if (!done)
		{
			image = new BufferedImage(xSize*scale*2,ySize*scale*3, BufferedImage.TYPE_INT_RGB);

			System.err.println("complete redraw, but suppressing flicker");

			Graphics2D g2 = image.createGraphics();
			g2.drawString("Gridracer",40,40);

			g2.drawRect(originX-1, originY-1, xSize*scale+1, ySize*scale+1);

			for(int y=0; y<ySize; y++){

				for(int x=0; x<xSize; x++){

					g2 = getColor(terrain[y][x],(Graphics2D)g2);
					g2.fillRect(originX+x*scale, originY+y*scale, scale, scale);

					//draw checkpoints
					g2.setColor(Color.white);
	  				for(int i = 0; i<checkpoints.length; i+=2) {
						int xcoord1 = originX + checkpoints[i][0] * scale;
						int ycoord1 = originY + checkpoints[i][1] * scale;
						int xcoord2 = originX + checkpoints[i+1][0] * scale;
						int ycoord2 = originY + checkpoints[i+1][1] * scale;
						g2.drawLine(xcoord1, ycoord1, xcoord2, ycoord2);
					}

				}
			}
		}
			done = true;


			g.drawImage(image,0,0,null);

			for(int i = 0; i < cars.size(); i++)
			{
				g.setColor(CarColors[i]);
				g.fillRect(originX+cars.get(i).getX()*scale, originY+cars.get(i).getY()*scale, scale, scale);
			}

	}


	public int[][] getTrack(String trackFile) throws IOException{

   	int[][] circuit;
		String thisLine = "";

		FileInputStream fis = new FileInputStream(trackFile);
		BufferedReader myInput = new BufferedReader(new InputStreamReader(fis));

		// Skip first two lines
		thisLine=myInput.readLine();
		thisLine=myInput.readLine();
		thisLine=myInput.readLine();
		int maxX=thisLine.length()-1;
		int maxY=1;
		while ((thisLine = myInput.readLine()) != null) {
			maxY++;
		}
		this.xSize=maxX;
		this.ySize=maxY;
   	circuit= new int[maxY][maxX];

		fis = new FileInputStream(trackFile);
		myInput = new BufferedReader(new InputStreamReader(fis));

		// Skip first two lines
		thisLine=myInput.readLine();
		thisLine=myInput.readLine();

		int y=0;

		while ((thisLine = myInput.readLine()) != null) {
			for(int x=0; x<thisLine.length()-1; x++){
				circuit[y][x]=(int)thisLine.charAt(x)-48;
			}
			y++;
		}

		return circuit;
	}

}
